﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;

//struct xin
//{
//	int _x;
//	int _y;
//};

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}

	Date(const Date& d)
		: _year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date(const Date& d)" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

/*int main()
{
	//C++98
	int arr[5] = {1,2,3,4,5};

	xin x = { 1,9 };

	//C++11
	int x { 2 };//内置类型支持

	Date d1  { 2025, 8, 7 };//内置类型类型也支持
	//这里本质上是{2025,8,7}是构造了一个临时对象，临时对象再拷贝构造给d1,编译器优化后变成直接构造

	 const Date& d2  { 2025,1,1 };//这里d2引用的是{2025,1,1}构造的临时对象，临时对象具有常性要用const引用

	 // 需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
	 Date d3  { 2025 };

	 //Date d4 2025  报错  不支持 只有用{}初始化的，才允许将=省略
	 Date d4 = 2025;


	return 0;
}*/


// STL中的容器都增加了⼀个initializer_list的构造
// vector (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());
//list(initializer_list<value_type> il, const allocator_type& alloc = allocator_type());
//map(initializer_list<value_type> il, const key_compare& comp =key_compare(), const allocator_type& alloc = allocator_type());
// ...
/*template<class T>
class vector {
public:
	typedef T* iterator;
	vector(initializer_list<T> l)
	{
		for (auto e : l)
			push_back(e)
	}
private:
	iterator _start = nullptr;
	iterator _finish = nullptr;
	iterator _endofstorage = nullptr;
};*/
// 另外，容器的赋值也⽀持initializer_list的版本
//vector& operator= (initializer_list<value_type> il);
//map& operator= (initializer_list<value_type> il);


/*int main()
{
	std::initializer_list<int> mylist;
	mylist = { 10, 20, 30 };

	// 这⾥begin和end返回的值initializer_list对象中存的两个指针
	// 这两个指针的值跟i的地址跟接近，说明数组存在栈上
	int i = 0;
	cout << mylist.begin() << endl;
	cout << mylist.end() << endl;
	cout << &i << endl;

	// {}列表中可以有任意多个值
	// 这两个写法语义上还是有差别的，第⼀个v1是直接构造，
	// 第⼆个v2是构造临时对象+临时对象拷⻉v2 ,优化为直接构造
	vector<int> v1({ 1,2,3,4,5 });
	vector<int> v2 = { 1,2,3,4,5 };
	
	// 这⾥是pair对象的{}初始化和map的initializer_list构造结合到⼀起⽤了
	map<string, string> dict = { {"sort", "排序"}, {"string", "字符串"} };

	// initializer_list版本的赋值⽀持
	v1 = { 10,20,30,40,50 };

	return 0;
}*/

/*int main()
{
	// 左值：可以取地址
	// 以下的a、b、*p、s、s[0]就是常⻅的左值
	int a = 10;//变量a
	int* p = new int(0);
	*p = 10;//解引用的指针
	int b;
	b = 3;//赋值表达式中b
	string s("111111");//字符串字面量属于左值
	s[0] = 'x';
	cout << &a << endl;
	cout << p << endl;
	cout << &b << endl;
	cout << (void*)&s[0] << endl;
	// 右值：不能取地址
	double x = 1.1, y = 2.2;
	// 以下⼏个10、x + y、fmin(x, y)、string("11111")都是常⻅的右值
	int c = 10;
	int d = x + y;
	int e = fmin(x, y);//fmin() 返回右值
	string s1 = string("11111");//匿名对象
	//cout << &10 << endl;
	//cout << &(x+y) << endl;
	//cout << &(fmin(x, y)) << endl;
	//cout << &string("11111") << endl;
	return 0;
}*/

//int main()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常见的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//
//	cout << &c << endl;
//	cout << (void*)&s[0] << endl;
//
//	// 左值引用给左值取别名
//	int& r1 = b;
//	int*& r2 = p;
//	int& r3 = *p;
//	string& r4 = s;
//	char& r5 = s[0];
//
//	// 右值：不能取地址
//	double x = 1.1, y = 2.2;
//	// 以下几个10、x + y、fmin(x, y)、string("11111")都是常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//	string("11111");
//
//	//cout << &10 << endl;
//	//cout << &(x+y) << endl;
//	//cout << &(fmin(x, y)) << endl;
//	//cout << &string("11111") << endl;
//
//	// 右值引用给右值取别名
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	string&& rr4 = string("11111");
//
//	// 左值引用不能直接引用右值，但是const左值引用可以引用右值
//	const int& rx1 = 10;
//	const double& rx2 = x + y;
//	const double& rx3 = fmin(x, y);
//	const string& rx4 = string("11111");
//
//	// 右值引用不能直接引用左值，但是右值引用可以引用move(左值)
//	int&& rrx1 = move(b);
//	int*&& rrx2 = move(p);
//	int&& rrx3 = move(*p);
//	string&& rrx4 = move(s);
//	//底层就是强制转换
//	string&& rrx5 = (string&&)s;
//
//	// b、r1、rr1都是变量表达式，都是左值
//	cout << &b << endl;
//	cout << &r1 << endl;
//	cout << &rr1 << endl;
//
//	// int&& rr1 = 10;
//	// 这里要注意的是，rr1的属性是左值，所以不能再被右值引用绑定，除非move一下
//
//	//int&& rrx6 = rr1;
//	int&& rrx6 = move(rr1);
//
//	return 0;
//}

//int main()
//{
//	std::string s1 = "Test";//“Test”是右值
//	//std::string&& r1 = s1; // 错误：s1是左值，不能直接被右值引用绑定
//	//std::string&& r1 = move(s1); 要move一下才可以
//
//
//	const std::string& r2 = s1 + s1; // OK：到 const 的左值引⽤延⻓生命周期
//	// r2 += "Test"; // 错误：不能通过到 const 的引⽤修改
//
//	std::string&& r3 = s1 + s1; // OK：右值引⽤延长生命周期
//	r3 += "Test"; // OK：能通过到非 const 的引⽤修改
//	std::cout << r3 << '\n';
//	return 0;
//}


class LifetimeTracker {
public:
	LifetimeTracker(const char* name) : name(name) {
		std::cout << "构造: " << name << std::endl;
	}

	~LifetimeTracker() {
		std::cout << "析构: " << name << std::endl;
	}

private:
	const char* name;
};

// 测试函数
void test() {
	std::cout << "\n=== 进入 test() 函数 ===" << std::endl;

	// 场景1：临时对象无引用绑定 (立即析构)
	std::cout << "\n[无引用] 临时对象创建..." << std::endl;
	LifetimeTracker("临时对象");
	//本质"临时对象"会生成一个临时对象，用临时对象构造一个LifetimeTracker对象
	// 跳过这一行之后，临时对象的生命周期结束，立刻调了析构
	std::cout << "临时对象立即析构 (已显示在上行)" << std::endl;

	// 场景2：const 左值引用绑定
	std::cout << "\n[const左值引用] 创建临时对象..." << std::endl;
	const LifetimeTracker& const_ref = LifetimeTracker("const引用延长");
	//本质是"const引用延长“会生成一个临时对象，用临时对象构造一个LifetimeTracker对象，
	// 再拷贝构造给const_ret,这里就一步构造，其生命周期会延长到与引用相同的作用域
	std::cout << "临时对象仍存在 (尚未析构)" << std::endl;

	// 场景3：右值引用绑定
	std::cout << "\n[右值引用] 创建临时对象..." << std::endl;
	LifetimeTracker&& rvalue_ref = LifetimeTracker("右值引用延长");
	//同理
	std::cout << "临时对象仍存在 (尚未析构)" << std::endl;

	std::cout << "\n=== 即将离开 test() 函数 ===" << std::endl;
} // 此处所有引用离开作用域，绑定对象析构

//int main() {
//	test();
//	std::cout << "\n=== 返回 main() ===" << std::endl;
//	return 0;
//}

void f(int& x)
{
	std::cout << "左值引用重载 f(" << x << ")\n";
} 

void f(const int& x)
{
	std::cout << "const 的左值引用重载 f(" << x << ")\n";
} 

void f(int&& x)
{
	std::cout << "右值引用重载 f(" << x << ")\n";
} 

//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//
//	// 右值引变用量在用于表达式时是左值（右值1被右值引用引用之后，其x的属性是左值）
//	int && x = 1;
//	f(x); // 调⽤ f(int& x)
//	f(std::move(x)); // 调⽤ f(int&& x)
//	return 0;
//}

//class Solution {
//public:
//	 这⾥的传值返回拷⻉代价就太⼤了
//	vector<vector<int>> generate(int numRows) {
//		vector<vector<int>> vv(numRows);
//		for (int i = 0; i < numRows; ++i)
//		{
//			vv[i].resize(i + 1, 1);
//		}
//
//		for (int i = 2; i < numRows; ++i)
//		{
//			for (int j = 1; j < i; ++j)
//			{
//				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//			}
//		}
//
//		return vv;
//	}
//};


//class Solution {
//public:
//	// 传值返回需要拷⻉
//	string addStrings(string num1, string num2) {
//		string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		return str;
//	}
//};
//
//int main()
//{
//	string ret;
//	// ...
//	ret = Solution().addStrings("11111111111111111111", "222222222222222222222222222");
//	cout << ret.c_str() << endl;
//	cout << &ret<< endl;
//
//	return 0;
// 
//}


#include<assert.h>
#include<string.h>
#include<algorithm>
#include"list.h"

namespace bit
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		const_iterator begin() const
		{
			return _str;
		}

		const_iterator end() const
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}

		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;

			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}

		// 移动构造
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			swap(s);
		}

		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷⻉赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}

			return*this;
		}

		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}

		~string()
		{
			cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}

				_str = tmp;
				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity *
					2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};
}
//}
//
//
//int main()
//{
//	//构造
//	bit::string s1("xxxxx");
//
//	// 拷贝构造
//	bit::string s2 = s1;
//
//	// 构造+移动构造，优化后直接构造
//	bit::string s3 = bit::string("yyyyy");
//
//	// 移动构造
//	bit::string s4 = move(s1);
//
//	//移动赋值
//	bit::string s5;
//	s5 = move(s4);
//
//	cout << "******************************" << endl;
//
//	return 0;
//}
//
//namespace bit
//{
//	string addStrings(string num1, string num2)
//	{
//		string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		cout << "******************************" << endl;
//		return str;
//	}
//} 
//
////场景1
//int main()
//{
//	bit::string ret = bit::addStrings("11111", "2222");
//	cout << ret.c_str() << endl;
//	return 0;
//}
//
//
//// 场景2
//int main()
//{
//	bit::string ret;
//	ret = bit::addStrings("11111", "2222");
//	cout << ret.c_str() << endl;
//	return 0;
//}



//int main()
//{
//	bit::list<bit::string> lt;
//	cout << "*************************" << endl;
//	bit::string s1("111111111111111111111");
//	lt.push_back(s1);
//	cout << "*************************" << endl;
//	lt.push_back(bit::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	return 0;
//}

//// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
//template<class T>
//void f1(T& x)
//{}
//// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
//template<class T>
//void f2(T&& x)
//{}
//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&& （只有右值引用的右值引用才为右值引用）
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0);  报错 f1实例化后总为左值 而0是右值
//	
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0);  报错 同理
//	
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0);  报错 同理
//	
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);//const左值引用可以引用右值
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n);  报错 n是左值
//	f2<int>(0);
//
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); 报错 0是右值
//	
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n);  报错 n是左值
//	f2<int&&>(0);
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//	cout << &a << endl;
//	cout << &x << endl << endl;
//} 
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// b是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int& t)
//   // 所以Function内部会编译报错，x不能++
//   Function(b); // const 左值
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//	return 0;
//}

////与标准库的forward进行区分
//namespace xin
//{
//	template <class _Ty>
//	_Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
//	{ // forward an lvalue as either an lvalue or an rvalue
//		return static_cast<_Ty&&>(_Arg);
//	}
//
//	template <class _Ty>
//	_Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept
//	{ // forward an lvalue as either an lvalue or an rvalue
//		return static_cast<_Ty&&>(_Arg);
//	}
//
//}
//
//
//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<class T>
//void Function(T&& t)
//{
//	Fun(xin::forward<T>(t));
//} 
//
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值引用
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值引用
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值引用
//	const int b = 8;
//
//	// b是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//	Function(b); // const 左值引用
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	Function(std::move(b)); // const 右值引用
//	return 0;
//}

//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);
//
//void Print()
//{
//	//..
//}
//template <class T1>
//void Print(T1&& arg1)
//{
//	//...
//}
//template <class T1, class T2>
//void Print(T1&& arg1, T2&& arg2)
//{
//	//...
//}
//template <class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3)
//{
//	//...
//}


//template <class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;//izeof...运算符去计算参数包中参数的个数
//} 
//
//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("xxxxx")); // 包⾥有2个参数
//	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数
//	return 0;
//}
//#include"list"
//int main()
//{
//	list<bit::string> lt;
//	// 传左值，跟push_back⼀样，走拷⻉构造
//	bit::string s1("111111111111");
//	lt.emplace_back(s1);
//	cout << "*********************************" << endl;
//
//	// 右值，跟push_back⼀样，⾛移动构造
//	lt.emplace_back(move(s1));
//	cout << "*********************************" << endl;
//
//	// 直接把构造string参数包往下传，直接⽤string参数包构造string
//    // 这⾥达到的效果是push_back做不到的
//	lt.emplace_back("111111111111");
//	cout << "*********************************" << endl;
//
//	list<pair<bit::string, int>> lt1;
//	// 跟push_back⼀样
//	// 构造pair + 拷⻉/移动构造pair到list的节点中data上
//	pair<bit::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	cout << "*********************************" << endl;
//
//	// 跟push_back⼀样
//	lt1.emplace_back(move(kv));
//	cout << "*********************************" << endl;
//
//	// 直接把构造pair参数包往下传，直接⽤pair参数包构造pair
//	// 这⾥达到的效果是push_back做不到的
//	lt1.emplace_back("苹果", 1);
//	cout << "*********************************" << endl;
//	return 0;
//}

class Person
{
	public :
	Person(const char* name = "", int age = 0)
		: _name(name)
		, _age(age)
	{}
	Person(const Person& p)
	:_name(p._name)
	,_age(p._age)
	{}
	Person(Person&& p) = default;
	//Person(const Person& p) = delete;

private:
	bit::string _name;
	int _age;
};
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	Person s4;
//	//s4 = std::move(s2);
//	return 0;
//}

//int main()
//{
//	// ⼀个简单的lambda表达式
//	auto add1 = [](int x, int y)->int {return x + y; };
//	cout << add1(1, 2) << endl;
//
//	// 1、捕捉为空也不能省略
//	// 2、参数为空可以省略
//	// 3、返回值可以省略，可以通过返回对象⾃动推导
//	// 4、函数题不能省略
//	auto func1 = []
//	{
//			cout << "hello bit" << endl;
//			return 0;
//	};
//	func1();
//	int a = 0, b = 1;
//	auto swap1 = [](int& x, int& y)
//	{
//			int tmp = x;
//			x = y;
//			y = tmp;
//	};
//	swap1(a, b);
//	cout << a << ":" << b << endl;
//	return 0;
//}

//int x = 0;
//// 捕捉列表必须为空，因为全局变量不⽤捕捉就可以⽤，没有可被捕捉的变量
//auto func1 = []()
//{
//		x++;
//};
//
//int main()
//{
//	// 只能⽤当前lambda局部域和捕捉的对象和全局对象
//	int a = 0, b = 1, c = 2, d = 3;
//	auto func1 = [a, &b]
//	{
//			// 值捕捉的变量不能修改，引⽤捕捉的变量可以修改
//			//a++;
//			b++;
//			int ret = a + b;
//			return ret;
//	};
//	cout << func1() << endl;
//	// 隐式值捕捉
//	// 用了哪些变量就捕捉哪些变量
//	auto func2 = [=]
//		{
//			int ret = a + b + c;
//			return ret;
//		};
//	cout << func2() << endl;
//	// 隐式引⽤捕捉
//	// ⽤了哪些变量就捕捉哪些变量
//	auto func3 = [&]
//		{
//			a++;
//			c++;
//			d++;
//		};
//	func3();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	// 混合捕捉1
//	auto func4 = [&, a, b]
//		{
//			//a++;
//			//b++;
//			c++;
//			d++;
//			return a + b + c + d;
//		};
//	func4();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	// 混合捕捉2
//	auto func5 = [=, &a, &b]
//		{
//			a++;
//			b++;
//			/*c++;
//			d++;*/
//			return a + b + c + d;
//		};
//	func5();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	// 局部的静态和全局变量不能捕捉，也不需要捕捉
//	static int m = 0;
//	auto func6 = []
//		{
//			int ret = x + m;
//			return ret;
//		};
//	// 传值捕捉本质是一种拷⻉,并且被const修饰了
//	// mutable相当于去掉const属性，可以修改了
//	// 但是修改了不会影响外⾯被捕捉的值，因为是⼀种拷贝
//	auto func7 = [=]()mutable
//		{
//			a++;
//			b++;
//			c++;
//			d++;
//			return a + b + c + d;
//		};
//	cout << func7() << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//	return 0;
//}

//struct Goods
//{
//	string _name; // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	// ...
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//
//struct ComparePriceLess
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "⾹蕉", 3, 4 }, { "橙⼦", 2.2, 3
//	}, { "菠萝", 1.5, 4 } };
//	// 类似这样的场景，我们实现仿函数对象或者函数指针支持商品中
//	// 不同项的比较，相对还是比较麻烦的，那么这里lambda就很好⽤了
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price < g2._price;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price > g2._price;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate < g2._evaluate;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate > g2._evaluate;
//		});
//	return 0;
//}

class Rate
{
	public :
	Rate(double rate)
		: _rate(rate)
	{}
	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};
int main()
{
	double rate = 0.49;
	// lambda
	auto r2 = [rate](double money, int year) {
		return money * rate * year;
		};
	// 函数对象
	Rate r1(rate);
	r1(10000, 2);
	r2(10000, 2);
	auto func1 = [] {
		cout << "hello world" << endl;
		};
	func1();
	return 0;
}